package com.example.bm.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.bm.system.pojo.MenuTree;
import com.example.bm.system.service.RoleService;
import com.example.dao.mapper.TRoleMapper;
import com.example.dao.mapper.TRoleMenuMapper;
import com.example.dao.model.TMenu;
import com.example.dao.model.TRole;
import com.example.dao.model.TRoleMenu;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 用户service
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class RoleServiceImpl extends ServiceImpl<TRoleMapper, TRole> implements RoleService {

    @Resource
    private TRoleMenuMapper roleMenuService;

    /**
     * 查询列表, 自定义分页
     *
     * @param params
     * @return
     */
    @Override
    public Page<TRole> getPageList(Map<String, Object> params, int pageNum, int pageSize) {
        return PageHelper.startPage(pageNum, pageSize).doSelectPage(() -> this.baseMapper.findList(params));
    }

    /**
     * 不分页
     *
     * @param params
     * @return
     */
    @Override
    public List<TRole> getList(Map<String, Object> params) {
        return this.baseMapper.findList(params);
    }


    /**
     * 新增
     *
     * @param info
     */
    @Override
    @Transactional
    public void createInfo(TRole info, Map<String, String> params) {
        this.save(info);
        //选中权限
        String roleIds = params.get("checkedData");
        if (!StringUtils.isBlank(roleIds)) {
            List<MenuTree> roleArr = JSON.parseArray(params.get("checkedData"), MenuTree.class);
            List<TMenu> m = Lists.newArrayList();
            List<TMenu> menus = convertMenuTree(roleArr, m);
            menus.forEach(role -> {
                TRoleMenu entity = TRoleMenu.builder().roleId(info.getId()).menuId(role.getId()).build();
                roleMenuService.insert(entity);
            });
        }
    }

    /**
     * 更新
     *
     * @param info
     */
    @Override
    @Transactional
    public void updateInfo(TRole info, Map<String, String> params) {
        //更新角色信息
        this.saveOrUpdate(info);
        //删除角色关联菜单
        LambdaQueryWrapper<TRoleMenu> wrapper = new LambdaQueryWrapper<TRoleMenu>()
                .eq(TRoleMenu::getRoleId, info.getId());
        roleMenuService.delete(wrapper);
        //更新角色菜单
        String roleIds = params.get("checkedData");
        if (!StringUtils.isBlank(roleIds)) {
            List<MenuTree> roleArr = JSON.parseArray(params.get("checkedData"), MenuTree.class);
            List<TMenu> m = Lists.newArrayList();
            List<TMenu> menus = convertMenuTree(roleArr, m);
            menus.forEach(role -> {
                TRoleMenu entity = TRoleMenu.builder().roleId(info.getId()).menuId(role.getId()).build();
                roleMenuService.insert(entity);
            });
        }
    }


    /**
     * 删除菜单
     *
     * @param info
     */
    @Override
    @Transactional
    public void deleteInfo(TRole info) {
        //删除 角色
        this.baseMapper.deleteById(info.getId());
        //删除 角色管理菜单
        LambdaQueryWrapper<TRoleMenu> wrapper = new LambdaQueryWrapper<TRoleMenu>()
                .eq(TRoleMenu::getRoleId, info.getId().toString());
        roleMenuService.delete(wrapper);
    }


    private List<TMenu> convertMenuTree(List<MenuTree> menus, List<TMenu> trees) {
        menus.forEach(menuTree -> {
            TMenu tree = new TMenu();
            tree.setId(Long.parseLong(menuTree.getId()));
            trees.add(tree);

            if (!CollectionUtil.isEmpty(menuTree.getChildren())) {
                convertMenuTree(menuTree.getChildren(), trees);
            }
        });
        return trees;
    }

}
